package com.quanshu.exchange.ui.gui.message;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Pair;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.gyf.barlibrary.ImmersionBar;
import com.hyphenate.EMConnectionListener;
import com.hyphenate.EMError;
import com.hyphenate.chat.EMClient;
import com.hyphenate.chat.EMConversation;
import com.hyphenate.chat.EMMessage;
import com.hyphenate.exceptions.HyphenateException;
import com.quanshu.exchange.R;
import com.quanshu.exchange.support.api.UserInterface;
import com.quanshu.exchange.support.chat.ChatCommonUtils;
import com.quanshu.exchange.support.chat.ChatConstant;
import com.quanshu.exchange.support.db.GroupDao;
import com.quanshu.exchange.support.db.UserDao;
import com.quanshu.exchange.support.entity.GroupEntity;
import com.quanshu.exchange.support.entity.UserEntity;
import com.quanshu.exchange.support.net.BaseResponse;
import com.quanshu.exchange.support.net.core.BaseObserver;
import com.quanshu.exchange.support.net.core.BaseTransformer;
import com.quanshu.exchange.support.net.core.NetClient;
import com.quanshu.exchange.support.utils.AppUtils;
import com.quanshu.exchange.support.utils.DateUtil;
import com.quanshu.exchange.support.utils.RxViewHelper;
import com.quanshu.exchange.ui.base.BaseFragment;
import com.quanshu.exchange.ui.base.MyApplication;
import com.quanshu.exchange.ui.base.listener.IRefresh;
import com.quanshu.exchange.ui.base.recycler.BaseViewHolder;
import com.quanshu.exchange.ui.base.recycler.DataDisplayer;
import com.quanshu.exchange.ui.base.recycler.LayoutWrapper;
import com.quanshu.exchange.ui.base.recycler.SingleAdapter;
import com.quanshu.exchange.ui.gui.login.LoginActivity;
import com.quanshu.exchange.ui.gui.message.chat.ChatActivity;
import com.quanshu.exchange.ui.gui.message.friends.MyFriendListActivity;
import com.quanshu.exchange.ui.gui.message.friends.SearchUserActivity;
import com.quanshu.exchange.ui.gui.message.group.CreateGroupActivity;
import com.quanshu.exchange.ui.gui.message.group.MyGroupsActivity;
import com.quanshu.exchange.ui.gui.message.group.RecommendGroupActivity;
import com.quanshu.exchange.ui.gui.message.group.SearchGroupActivity;
import com.quanshu.exchange.ui.gui.message.mass_send.MassMessageActivity;
import com.quanshu.exchange.ui.gui.qrcode.QrCodeActivity;
import com.quanshu.exchange.ui.widget.dragindicator.DragIndicatorView;
import com.trello.rxlifecycle2.components.support.RxAppCompatActivity;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import butterknife.BindView;

/**
 * Created by jye on 2017/12/6.
 */

public class MessageFragment extends BaseFragment implements IRefresh {

    @BindView(R.id.mroe_add)
    LinearLayout mroeAdd;
    @BindView(R.id.llt_recommend_group)
    LinearLayout lltRecommendGroup;
    @BindView(R.id.llt_my_group)
    LinearLayout lltMyGroup;
    @BindView(R.id.llt_my_friend)
    LinearLayout lltMyFriend;
    @BindView(R.id.message_recy)
    RecyclerView recyclerView;
    @BindView(R.id.message_main_title)
    RelativeLayout relativeLayoutTitle;
    //    @BindView(R.id.smartLayout)
//    SmartRefreshLayout smartLayout;
    @BindView(R.id.indiactor_view)
    TextView indiactorView;
    @BindView(R.id.inform_message_llt)
    LinearLayout informMessageLlt;
    private UserEntity currentUser;

    private List<EMConversation> conversationList;
    private SingleAdapter<EMConversation> adapter;

    private static final int CONVERSATION_LOAD_FINISH = 0x10;

    protected boolean isConflict;

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message message) {
            switch (message.what) {
                case 0:
//                    onConnectionDisconnected();
                    break;
                case 1:
//                    onConnectionConnected();
                    break;
                case CONVERSATION_LOAD_FINISH:
                    if (conversationList != null) {
                        if (adapter == null) {
                            initView();
                        }
                        adapter.setData(conversationList);
                    }
                    break;
                default:
                    break;
            }
        }
    };

    public static MessageFragment newInstance() {
        MessageFragment f = new MessageFragment();
        Bundle args = new Bundle();
        f.setArguments(args);
        return f;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        if (savedInstanceState != null && savedInstanceState.getBoolean(ChatConstant.ACCOUNT_CONFLICT, false))
            return;
        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public int setFragmentLayoutID() {
        return R.layout.fragment_message_layout;
    }

    @Override
    public void initView() {
        ImmersionBar.with(this).statusBarDarkFont(true).statusBarColorTransform(R.color.white).titleBar(relativeLayoutTitle).init();
        currentUser = MyApplication.getInstance().getCurrentUser();
        if (currentUser == null) {
            return;
        }
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        adapter = new SingleAdapter<>(new DataDisplayer<EMConversation>(getActivity(), R.layout.item_conversation_layout) {
            @Override
            public void bindData(BaseViewHolder holder, LayoutWrapper<EMConversation> wrapper, EMConversation conversation, int position) {
                String username = conversation.conversationId();
                if (conversation.getType() == EMConversation.EMConversationType.Chat) {
                    UserEntity userEntity = UserDao.getInstance().query(username);
                    if (userEntity != null) {
                        holder.setRoundImageUrl(R.id.head_portrait, userEntity.getAvatar(), R.drawable.default_avatar);
                        holder.setText(R.id.conversation_title, AppUtils.getUserName(userEntity));
                    } else {
                        holder.setImage(R.id.head_portrait, R.drawable.default_avatar);
                        holder.setText(R.id.conversation_title, "聊天");
                    }
                    holder.setVisibility(R.id.is_group_remark, View.GONE);
                } else if (conversation.getType() == EMConversation.EMConversationType.GroupChat) {
                    GroupEntity groupEntity = GroupDao.getInstance().query(username);
                    if (groupEntity != null) {
                        holder.setRoundImageUrl(R.id.head_portrait, groupEntity.getGroup_photo(), R.drawable.default_group_avatar);
                        holder.setText(R.id.conversation_title, groupEntity.getGroup_name());
                    } else {
                        holder.setImage(R.id.head_portrait, R.drawable.default_group_avatar);
                        holder.setText(R.id.conversation_title, "群聊");
                    }
                    holder.setVisibility(R.id.is_group_remark, View.VISIBLE);
                }
                if (conversation.getUnreadMsgCount() > 0) {
                    DragIndicatorView dragIndicatorView = holder.getView(R.id.indiactor_view);
                    if (conversation.getType() == EMConversation.EMConversationType.Chat) {
                        int num = conversation.getUnreadMsgCount();
                        holder.setVisibility(R.id.drag_layout, View.VISIBLE);
                        dragIndicatorView.setPadding(10, 10, 10, 10);
                        if (num > 99) {
                            holder.setText(R.id.indiactor_view, "99+");
                        } else {
                            holder.setText(R.id.indiactor_view, num + "");
                        }
                    } else {
                        dragIndicatorView.setPadding(17, 17, 17, 17);
                        holder.setVisibility(R.id.drag_layout, View.VISIBLE);
                        holder.setText(R.id.indiactor_view, "");
                    }
                } else {
                    holder.setVisibility(R.id.drag_layout, View.GONE);
                }
                if (conversation. getAllMsgCount() != 0) {
                    // show the content of latest message
                    EMMessage lastMessage = conversation.getLastMessage();
                    boolean isShow = isNeedShowLastMsg(lastMessage);
                    if (isShow) {
                        holder.setVisibility(R.id.conversation_last_message, View.VISIBLE);
                        holder.setVisibility(R.id.message_time, View.VISIBLE);
                        holder.setText(R.id.conversation_last_message, ChatCommonUtils.getMessageDigest(lastMessage, getContext()));
                        holder.setText(R.id.message_time, DateUtil.Time2Date(lastMessage.getMsgTime() + "", "MM-dd HH:mm"));
                    } else {
                        holder.setVisibility(R.id.conversation_last_message, View.GONE);
                        holder.setVisibility(R.id.message_time, View.GONE);
                    }
                }
                ((DragIndicatorView) (holder.getView(R.id.indiactor_view))).setOnDismissAction(view -> conversation.markAllMessagesAsRead());
                holder.setOnClickListener(view -> {
                    Intent intent = new Intent(getActivity(), ChatActivity.class);
                    if (conversation.getType() == EMConversation.EMConversationType.Chat) {
                        intent.putExtra("CHAT_TYPE", ChatConstant.CHAT_TYPE_SINGLE);
                    } else if (conversation.getType() == EMConversation.EMConversationType.GroupChat) {
                        intent.putExtra("CHAT_TYPE", ChatConstant.CHAT_TYPE_GROUP);
                    }
                    intent.putExtra("conversationID", conversation.conversationId());
                    startActivity(intent);
                });
            }
        });
        recyclerView.setAdapter(adapter);
    }

    private boolean isNeedShowLastMsg(EMMessage lastMessage) {
        String owner = null;
        try {
            owner = lastMessage.getStringAttribute(ChatConstant.Chat_group_owner);
        } catch (HyphenateException e) {
            e.printStackTrace();
        }

        boolean visibility = ChatCommonUtils.getChatMsgVisibility(lastMessage, owner,
                MyApplication.getInstance().getCurrentUser().getMemberid());
        return visibility;
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        currentUser = MyApplication.getInstance().getCurrentUser();
        if (hidden == false && !isConflict && currentUser != null) {
            doRefreshNotify();
            doRefreshMessage();
        }
        if (!hidden){
            ImmersionBar.with(this).statusBarDarkFont(true).statusBarColorTransform(R.color.white).titleBar(relativeLayoutTitle).init();
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        if (isConflict) {
            outState.putBoolean(ChatConstant.ACCOUNT_CONFLICT, true);
        }
    }

    @Override
    public void initListener() {

        RxViewHelper.getInstance().clicks(mroeAdd, aVoid -> doShowMessageMenuDialog());
        RxViewHelper.getInstance().clicks(lltRecommendGroup, aVoid -> {
            currentUser = MyApplication.getInstance().getCurrentUser();
            if (currentUser == null) {
                Intent intent = new Intent(getActivity(), LoginActivity.class);
                startActivity(intent);
                return;
            }
            Intent intent = new Intent(getActivity(), RecommendGroupActivity.class);
            startActivity(intent);
        });
        RxViewHelper.getInstance().clicks(informMessageLlt, aVoid -> {
            currentUser = MyApplication.getInstance().getCurrentUser();
            if (currentUser == null) {
                Intent intent = new Intent(getActivity(), LoginActivity.class);
                startActivity(intent);
                return;
            }
            Intent intent = new Intent(getActivity(), NotifyMessageListActivity.class);
            startActivity(intent);
        });
        RxViewHelper.getInstance().clicks(lltMyGroup, aVoid -> {
            currentUser = MyApplication.getInstance().getCurrentUser();
            if (currentUser == null) {
                Intent intent = new Intent(getActivity(), LoginActivity.class);
                startActivity(intent);
                return;
            }
            Intent intent = new Intent(getActivity(), MyGroupsActivity.class);
            startActivity(intent);
        });
        RxViewHelper.getInstance().clicks(lltMyFriend, aVoid -> {
            currentUser = MyApplication.getInstance().getCurrentUser();
            if (currentUser == null) {
                Intent intent = new Intent(getActivity(), LoginActivity.class);
                startActivity(intent);
                return;
            }
            Intent intent = new Intent(getActivity(), MyFriendListActivity.class);
            startActivity(intent);
        });
    }

    @Override
    protected void initData() {

    }

    private void doShowMessageMenuDialog() {
        DialogMessageMenu dialogMessageMenu = new DialogMessageMenu(getActivity());
        dialogMessageMenu.show();

        dialogMessageMenu.getBehaviorSubject().subscribe(rltTop -> {
            currentUser = MyApplication.getInstance().getCurrentUser();
            if (currentUser == null) {
                Intent intent = new Intent(getActivity(), LoginActivity.class);
                startActivity(intent);
                return;
            }
            dialogMessageMenu.dismiss();
        });

        dialogMessageMenu.getOneBehaviorSubject().subscribe(lltGroupSendMessage -> {
            currentUser = MyApplication.getInstance().getCurrentUser();
            if (currentUser == null) {
                Intent intent = new Intent(getActivity(), LoginActivity.class);
                startActivity(intent);
                return;
            }
            dialogMessageMenu.dismiss();
            Intent intent = new Intent(getActivity(), MassMessageActivity.class);
            startActivity(intent);
        });

        dialogMessageMenu.getTwoBehaviorSubject().subscribe(lltAddFriend -> {
            currentUser = MyApplication.getInstance().getCurrentUser();
            if (currentUser == null) {
                Intent intent = new Intent(getActivity(), LoginActivity.class);
                startActivity(intent);
                return;
            }
            dialogMessageMenu.dismiss();
            Intent intent = new Intent(getActivity(), SearchUserActivity.class);
            startActivity(intent);
        });

        dialogMessageMenu.getThreeBehaviorSubject().subscribe(lltAddGroup -> {
            currentUser = MyApplication.getInstance().getCurrentUser();
            if (currentUser == null) {
                Intent intent = new Intent(getActivity(), LoginActivity.class);
                startActivity(intent);
                return;
            }
            dialogMessageMenu.dismiss();
            Intent intent = new Intent(getActivity(), SearchGroupActivity.class);
            startActivity(intent);
        });

        dialogMessageMenu.getFourBehaviorSubject().subscribe(lltCreateGroup -> {
            currentUser = MyApplication.getInstance().getCurrentUser();
            if (currentUser == null) {
                Intent intent = new Intent(getActivity(), LoginActivity.class);
                startActivity(intent);
                return;
            }
            dialogMessageMenu.dismiss();
            Intent intent = new Intent(getActivity(), CreateGroupActivity.class);
            startActivity(intent);
        });

        dialogMessageMenu.getScanBehaviorSubject().subscribe(o -> {
            currentUser = MyApplication.getInstance().getCurrentUser();
            if (currentUser == null) {
                Intent intent = new Intent(getActivity(), LoginActivity.class);
                startActivity(intent);
                return;
            }
            dialogMessageMenu.dismiss();
            Intent intent = new Intent(getActivity(), QrCodeActivity.class);
            startActivity(intent);
        });
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        ImmersionBar.with(this).destroy();
    }

    @Override
    public void doRefreshNotify() {
        NetClient.getInstance()
                .getNetService(UserInterface.class)
                .getUnReadNotifiesNum(AppUtils.getSignParams(currentUser.getMemberid()), currentUser.getMemberid())
                .compose(new BaseTransformer<>((RxAppCompatActivity) getActivity()))
                .subscribe(new BaseObserver<BaseResponse<Integer>>() {
                    @Override
                    public void onSuccess(BaseResponse<Integer> response) {
                        long count = response.getInfo();
                        if (count > 0) {
                            indiactorView.setVisibility(View.VISIBLE);
                            indiactorView.setText(count + "");
                        } else {
                            indiactorView.setVisibility(View.GONE);
                        }
                    }

                    @Override
                    public void onFailure(Throwable e) {
                        indiactorView.setVisibility(View.GONE);
                    }
                });
    }

    @Override
    public void doRefreshMessage() {
        new Thread(() -> {
            conversationList = loadConversationList();
            if (conversationList != null) {
                handler.sendEmptyMessage(CONVERSATION_LOAD_FINISH);
            }
        }).start();
    }

    /**
     * load conversation list
     *
     * @return +
     */
    protected List<EMConversation> loadConversationList() {
        // get all conversations
        Map<String, EMConversation> conversations = EMClient.getInstance().chatManager().getAllConversations();
        List<Pair<Long, EMConversation>> sortList = new ArrayList<Pair<Long, EMConversation>>();
        synchronized (conversations) {
            for (EMConversation conversation : conversations.values()) {
                if (conversation.getAllMessages().size() != 0) {
                    sortList.add(new Pair<>(conversation.getLastMessage().getMsgTime(), conversation));
                }
            }
        }
        try {
            sortConversationByLastChatTime(sortList);
        } catch (Exception e) {
            e.printStackTrace();
        }
        List<EMConversation> list = new ArrayList<>();
        for (Pair<Long, EMConversation> sortItem : sortList) {
            list.add(sortItem.second);
        }
        return list;
    }

    /**
     * sort conversations according time stamp of last message
     *
     * @param conversationList
     */
    private void sortConversationByLastChatTime(List<Pair<Long, EMConversation>> conversationList) {
        Collections.sort(conversationList, (con1, con2) -> {
            if (con1.first.equals(con2.first)) {
                return 0;
            } else if (con2.first.longValue() > con1.first.longValue()) {
                return 1;
            } else {
                return -1;
            }
        });
    }

    @Override
    public void onResume() {
        super.onResume();
        currentUser = MyApplication.getInstance().getCurrentUser();
        if (currentUser != null) {
            doRefreshNotify();
            doRefreshMessage();
        }
    }

    protected EMConnectionListener connectionListener = new EMConnectionListener() {

        @Override
        public void onDisconnected(int error) {
            if (error == EMError.USER_REMOVED || error == EMError.USER_LOGIN_ANOTHER_DEVICE || error == EMError.SERVER_SERVICE_RESTRICTED
                    || error == EMError.USER_KICKED_BY_CHANGE_PASSWORD || error == EMError.USER_KICKED_BY_OTHER_DEVICE) {
                isConflict = true;
            } else {
                handler.sendEmptyMessage(0);
            }
        }

        @Override
        public void onConnected() {
            handler.sendEmptyMessage(1);
        }
    };

}
